﻿using System;
using System.Collections.Generic;
using System.Data.Services.Providers;
using System.Linq;
using System.Reflection;
using BookStoreService.Core.Models;

namespace BookStoreService.Core.Providers
{
    public class BookStoreUpdateProvider : IDataServiceUpdateProvider
    {
        private readonly BookStore m_bookStore;
        private readonly List<Action> m_pendingChanges = new List<Action>();
        public BookStoreUpdateProvider(BookStore bookStore)
        {
            m_bookStore = bookStore;
        }

        public object CreateResource(string containerName, string fullTypeName)
        {
            var book = new Book();
            // And register pending change to add the resource to the resource set list
            m_pendingChanges.Add(() => m_bookStore.Add(book));

            return book;
        }

        public object GetResource(IQueryable query, string fullTypeName)
        {
            object resource = Enumerable.Cast<object>(query).FirstOrDefault();

            return resource;
        }

        public object ResetResource(object resource)
        {
            return resource;
        }

        public void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            PropertyInfo propertyInfo = targetResource.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
            m_pendingChanges.Add(() => propertyInfo.SetValue(targetResource, propertyValue, null));

        }

        public object GetValue(object targetResource, string propertyName)
        {
            return null;
        }

        public void SetReference(object targetResource, string propertyName, object propertyValue)
        {
        }

        public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
        {
        }

        public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
        {
        }

        public void DeleteResource(object targetResource)
        {
        }

        public void SaveChanges()
        {
            if (m_pendingChanges.Count == 0) return;

            foreach (var pendingChange in m_pendingChanges)
            {
                pendingChange();
            }

            m_pendingChanges.Clear();
            m_bookStore.SubmitChanges();
        }

        public object ResolveResource(object resource)
        {
            return resource;
        }


        public void ClearChanges()
        {
        }

        public void SetConcurrencyValues(object resourceCookie, bool? checkForEquality, IEnumerable<KeyValuePair<string, object>> concurrencyValues)
        {

        }
    }
}